﻿using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor.Experimental.GraphView;
using System.Reflection;
using System.Collections;
using UnityEngine.UIElements;
using UnityEditor;

namespace SkillEditor
{
    public class SkillEditorSearchWindowProvider : ScriptableObject, ISearchWindowProvider
    {
        private Func<string, Node> _callback;

        public List<SearchTreeEntry> entries;

        private GraphView root => window.graph;

        private SkillEditorSpaceWindow window;

        public void Initialize(SkillEditorSpaceWindow window, Func<string, Node> callback)
        {
            this.window = window;
            this._callback = callback;

            entries = new List<SearchTreeEntry>();
            entries.Add(new SearchTreeGroupEntry(new GUIContent("Create Node"), 0) { userData = "" });

            Hashtable hash = new Hashtable();
            Hashtable hashTemp = null;

            foreach (var item in window.dicNodeInfo)
            {
                hashTemp = hash;
                var info = item.Value;

                if (hashTemp.ContainsKey(info.group) == false)
                {
                    hashTemp[info.group] = new Hashtable();
                }

                (hashTemp[info.group] as Hashtable)[info.id] = new Hashtable();
            }

            AddEntry(1, hash, entries, "");

            entries.Sort(SortEntriesHandler);
        }

        private int SortEntriesHandler(SearchTreeEntry x, SearchTreeEntry y)
        {
            return x.userData.ToString().CompareTo(y.userData.ToString());
        }

        List<SearchTreeEntry> ISearchWindowProvider.CreateSearchTree(SearchWindowContext context)
        {
            return entries;
        }

        private void AddEntry(int level, Hashtable hash, List<SearchTreeEntry> entries, string group)
        {
            foreach (string key in hash.Keys)
            {
                Hashtable h = hash[key] as Hashtable;

                if (h.Count > 0)
                {
                    entries.Add(new SearchTreeGroupEntry(new GUIContent(key)) { level = level, userData = key });
                    AddEntry(level + 1, h, entries, key);
                }
                else
                {
                    entries.Add(new SearchTreeEntry(new GUIContent(key)) { level = level, userData = group + "." + key });
                }
            }
        }

        bool ISearchWindowProvider.OnSelectEntry(SearchTreeEntry searchTreeEntry, SearchWindowContext context)
        {
            string key = searchTreeEntry.userData as string;
            int index = key.IndexOf('.');
            key = key.Substring(index + 1, key.Length - index - 1);
            Node node = _callback(key);           
            Vector2 p = context.screenMousePosition - window.position.position - root.contentViewContainer.worldBound.position;
            node.SetPosition(new Rect(p, new Vector2()));
            return true;
        }
    }
}